﻿package com.example.android.BluetoothChat;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;

import android.util.Log;


/*
 * 目前存在的BUG，经常请求aborted，而且在内存卡上创建文件，，这些文件是javascrip创建的？？
 */
/* ConnnectionThread类完成与一个Web浏览器的通信 */
public  class  HttpServer  extends Thread 
{
	  Socket client; // 连接Web浏览器的socket字
      int counter; // 计数器
     // OutputStream outstream;
      ByteArrayOutputStream byteoutputstream;
      int jpeglength;
      
      public  HttpServer(Socket cs , int num , ByteArrayOutputStream  bauts , int jpglen)
      {
    	  client = cs;
    	  counter = num;
    	  byteoutputstream = bauts;
    	  jpeglength = jpglen;
      }
      
      public void run() // 线程体
     {
		try 
		{
			String destIP=client.getInetAddress().toString(); // 客户机IP地址
			int destport=client.getPort(); // 客户机端口号
			Log.i("cyy","cyy...Connection "+counter+":connected to "+destIP+" on port "+destport+".");
			//PrintStream outstream=new PrintStream(client.getOutputStream());
			DataOutputStream outstream=new DataOutputStream(client.getOutputStream());
			DataInputStream instream=new DataInputStream(client.getInputStream());
			String inline=instream.readLine(); // 读取Web浏览器提交的请求信息
			Log.i("cyy","cyy...Received:"+inline);
			if (getrequest(inline))
			{ // 如果是GET请求
					String filename=getfilename(inline);
									
					String jpegname = filename.substring(filename.indexOf('.')+1);
						
					//如果是获取请求Jpeg帧，则直接发送Jpge流过去。
					if(jpegname.equals("jpg"))
					{
						Log.i("cyy","cyy...jpeg:"+filename+" requested.");
						
						String sendhtml;
					    sendhtml = "HTTP/1.0 200 OK\n"+"MIME_version:1.0\n"+
				        "Content_Type:text/html\n"+"Content_Length:"+ jpeglength +"\n" + "\n";
						
						senfjpegstream(outstream , byteoutputstream , sendhtml.getBytes());
						
					}else//请求的是其他文件，则在webserver上面寻找该文件，如果找到了，则发送过去。
					{
						
						//找到了原因，抓包工具分析，，只发了HTTP/1.0 200 0K，其他 的没有发送出去？？
						//使用DataOutputStream流，，发送出去了。
						 Log.i("cyy","cyy...file :"+filename+" ,beging to search");
						    
						   // filename = "/sdcard/" + filename;
						    
							File file=new File("/sdcard/"+filename);
							String sendhtml;
							if (file.exists()) 
							{ // 若文件存在，则将文件送给Web浏览器
								Log.i("cyy","cyy...file:"+filename+" exists!.");
								Log.i("cyy","cyy...file:"+filename+" requested.");
								int len=(int)file.length();
								
							   // sendhtml = "HTTP/1.0 200 OK\r\n"+"MIME_version:1.0\r\n"+
							   // "Content_Type:text/html\r\n"+"Content_Length:"+len+"\r\n" + "\r\n";
							    
							    sendhtml = "HTTP/1.0 200 OK\n"+"MIME_version:1.0\n"+
						        "Content_Type:text/html\n"+"Content_Length:"+len+"\n" + "\n";
							    
							    //outstream.write(sendhtml.getBytes());
							    
								sendfile(outstream , file , sendhtml.getBytes()); // 发送文件
							    outstream.flush();
								
					        }else 
							{ // 文件不存在时
					        	   Log.i("cyy","cyy...clien's requeset file:"+file.getName()+"not exits!");
									String notfound="<html><head><title>Not Found</title></head><body><h1>Error 404-file not found</h1></body></html>";
									
									
									/*
									outstream.println("HTTP/1.0 404 no found");
									outstream.println("Content_Type:text/html");
									outstream.println("Content_Length:"+notfound.length()+2);
									outstream.println("");
									outstream.println(notfound);
									outstream.flush();
									*/
							}
					}
																		
			}
	          long m1=1; 
	         // while (m1<11100000) {m1++;} // 延时
	          //sleep(10);
	          //发送完毕就关闭socket，非常重要，节省资源
	          client.close();
	      }catch (Exception e)
	      {
			// TODO: handle exception
		  } //endtry
	}//endrun
      
	/* 获取请求类型是否为“GET” */
	boolean getrequest(String s)
	{ 
		if(s.length()>0)
		{
		   if(s.substring(0,3).equalsIgnoreCase("GET"))
			   return true;
		}
		return false;
	}

	String getfilename(String s) 
	{
				String f=s.substring(s.indexOf(' ')+1);
				f=f.substring(0,f.indexOf(' '));
				try 
				{
				   if(f.charAt(0)=='/')
				   f=f.substring(1);
				}catch(StringIndexOutOfBoundsException e)
				{
				   System.out.println("Exception:"+e);
				}
				if(f.equals("")) 
					f="index.html";
				 return f;
	}

				/*把指定文件发送给Web浏览器 */ 
	void sendfile(DataOutputStream outs,File file , byte[] httphead)
	{
	    try{
				DataInputStream in=new DataInputStream(new FileInputStream(file));
				
				int datalen =(int)file.length();
				int headlen = httphead.length;
				byte buf[]=new byte[headlen + datalen];
				
				System.arraycopy(httphead, 0, buf , 0 , headlen);
			
				in.readFully(buf ,headlen , datalen );
				
				outs.write(buf , 0 , buf.length);
				Log.i("cyy","cyy...sendfile to client sucsessed!");
				outs.flush();
				in.close();
	       }catch (Exception e)
	        {
	    	   Log.i("cyy","cyy...sendfile catch Exception");
			  e.printStackTrace();
		    }	       
	       
	}//endsendfile
	
	void senfjpegstream(DataOutputStream outs, ByteArrayOutputStream  bauts ,  byte[] httphead)
	{
	    try
	    {
			
			int datalen = jpeglength;
			int headlen = httphead.length;
			byte buf[]=new byte[headlen + datalen];
			
			System.arraycopy(httphead, 0, buf , 0 , headlen);
		    System.arraycopy(bauts.toByteArray(), 0, buf, headlen , datalen);
			
			outs.write(buf , 0 , buf.length);
	    	
			Log.i("cyy","cyy...sendjpeg stream to client sucsessed!");
			Log.i("cyy" , "cyy...sendjpeg....httpheadlength is "+headlen+"jpeglength is "+datalen);
			outs.flush();
			
			//重置bauts数组，该用足用于存数Jepg帧数据
			bauts.reset();
			Log.i("cyy" , "cyy... Reset Jpeg ByteArray");
       }catch (Exception e)
        {
    	   Log.i("cyy","cyy...sendjpegstream catch Exception");
		   e.printStackTrace();
	    }
	}

 }


